import { getJWTPayload } from '@/common/Utils'
import WebSocket from 'ws'
import Comments from '@/model/Comments'
//
class WebSocketServer {
  constructor(config = {}) {
    const defaultConfig = {
      port: 3001,
      timeInterval: 30 * 1000,
      isAuth: true,
    }
    //最终的配置
    const finalConfig = { ...defaultConfig, ...config }
    this.ws = {}
    this.timeInterval = finalConfig.timeInterval
    this.isAuth = finalConfig.isAuth
    this.port = finalConfig.port
    this.options = config.options || {}
  }
  init() {
    this.wss = new WebSocket.Server({ port: this.port, ...this.options })
    //心跳检测
    //连接信息
    this.wss.on('connection', (ws) => {
      ws.isAlive = true
      ws.on('message', (msg) => this.onMessage(ws, msg))
      ws.on('close', () => this.onClose(ws))
    })
  }
  onMessage(ws, msg) {
    //用户鉴权
    //心跳检测
    // this.heartbeat()
    //信息发送
    const msgObj = JSON.parse(msg)
    const events = {
      auth: async () => {
        try {
          const obj = await getJWTPayload(msgObj.message)
          if (obj) {
            ws.isAuth = true
            ws._id = obj._id
            const num = await Comments.getTotal(obj._id)
            ws.send(
              JSON.stringify({
                event: 'message',
                message: num,
              })
            )
          }
        } catch (error) {
          ws.send(
            JSON.stringify({
              event: 'noauth',
              message: 'palese auth again',
            })
          )
        }
      },
      heartbeat: () => {
        if (msgObj.message === 'pong') {
          ws.isAlive = true
        }
      },
      message: () => {
        //鉴权拦截
        if (!ws.isAuth && this.isAuth) {
          return
        }
        this.wss.clients.forEach((client) => {
          if (client.readyState === WebSocket.OPEN && client._id === ws._id) {
            this.send(msg)
          }
        })
      },
    }
    events[msgObj.event]()
  }
  //点对点消息发送
  send(uid, msg) {
    this.wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN && client._id === uid) {
        client.send(msg)
      }
    })
  }

  //广播消息 ->推送系统消息
  broadcase(msg) {
    this.wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(msg)
      }
    })
  }
  onClose() {}
  heartbeat() {
    clearInterval(this.interval)
    this.interval = setInterval(() => {
      this.wss.clients.forEach((ws) => {
        if (!ws.isAlive && ws.room) {
          delete ws.room
          return ws.terminate() //ws 终止websocke方法
        }
        //主动发送心跳请求
        // 客户端返回了消息，主动设置flag为在线
        ws.isAlive = false
        ws.send(
          JSON.stringify({
            event: 'heartbeat',
            message: 'ping',
          })
        )
      })
    }, this.timeInterval)
  }
}

export default WebSocketServer
